package com.supermap.panes;

import com.supermap.Helper;
import com.supermap.data.*;
import com.supermap.data.Enum;
import com.supermap.panes.advance.SettingPane;
import com.supermap.realspace.*;
import com.supermap.ui.Action3D;
import com.supermap.ui.SceneControl;
import com.supermap.ui.Tracking3DListener;

import javax.swing.*;
import java.awt.*;
import java.util.HashMap;

public class SlopeAndAspectAnalystPane extends SettingPane {
    private SceneControl sceneControl;

    private JComboBox<SlopeDisplayMode> slopeDisplayModeCmb;
    private JTextField transparencyTxt;
    private JTextField minVisibleValueTxt;
    private JTextField maxVisibleValueTxt;
    private JCheckBox isArrowMoveCbx;
    private JCheckBox isShowSlopeAndAspectInfoChb;

    private SlopeSetting slopeSetting;
    private Tracking3DListener tracking3DListener = tracking3DEvent -> {
        Geometry3D geometry = tracking3DEvent.getGeometry();
        Action3D action3D = sceneControl.getAction();
        if (action3D == Action3D.CREATE_POLYGON && geometry instanceof GeoRegion3D) {
            GeoRegion3D geoRegion3D = (GeoRegion3D) geometry;
            if (geoRegion3D.getPartCount() > 0) {
                generateSlopeSetting(geoRegion3D);
                sceneControl.getScene().getTerrainLayers().setSlopeSetting(slopeSetting);
            }
        }
        if (action3D == Action3D.CREATE_POINT) {
            Point3D point3D = new Point3D(tracking3DEvent.getX(), tracking3DEvent.getY(), tracking3DEvent.getZ());
            Scene scene = sceneControl.getScene();
            TerrainLayers terrainLayers = scene.getTerrainLayers();
            double slopeValue = terrainLayers.getSlopeValue(point3D);
            double slopeDirectionValue = terrainLayers.getSlopeDirectionValues(point3D);

            TextStyle textStyle = new TextStyle();
            textStyle.setSizeFixed(true);
            textStyle.setFontName("微软雅黑");
            textStyle.setForeColor(Color.BLACK);
            textStyle.setFontScale(2);
            textStyle.setFontHeight(3);

            TextPart3D textPart3D = new TextPart3D();
            textPart3D.setText("X: " + point3D.getX() + "\nY: " + point3D.getY() + "\nZ: " + point3D.getZ() + "\n坡度: " + slopeValue + "\n坡向: " + slopeDirectionValue);
            textPart3D.setAnchorPoint(point3D);
            GeoText3D geoText3D = new GeoText3D(textPart3D);
            geoText3D.setTextStyle(textStyle);
            GeoStyle3D geoStyle3D = new GeoStyle3D();
            geoStyle3D.setAltitudeMode(AltitudeMode.ABSOLUTE);
            geoStyle3D.setBottomAltitude(10);
            geoText3D.setStyle3D(geoStyle3D);
            TrackingLayer3D trackingLayer = sceneControl.getScene().getTrackingLayer();
            int textTagIndex = trackingLayer.indexOf("Text");
            if (textTagIndex != -1) {
                trackingLayer.remove(textTagIndex);
            }
            trackingLayer.add(geoText3D, "Text");
        }
    };

    public SlopeAndAspectAnalystPane(String title, SceneControl sceneControl) {
        super(title, new Object[]{sceneControl});
    }

    @Override
    protected void initializeArgs(Object[] args) {
        sceneControl = (SceneControl) args[0];
    }

    @Override
    protected void initializeCore() {
        this.confirmBtn.setVisible(false);
        super.mainPanel.setLayout(new BorderLayout());

        JToolBar toolBar = new JToolBar();
        super.mainPanel.add(toolBar, BorderLayout.NORTH);

        JButton drawRectBtn = new JButton("绘制");
        toolBar.add(drawRectBtn);
        drawRectBtn.addActionListener(e -> {
            sceneControl.setAction(Action3D.CREATE_POLYGON);
            sceneControl.addTrackingListener(tracking3DListener);
        });

        JButton clearBtn = new JButton("清空");
        toolBar.add(clearBtn);
        clearBtn.addActionListener(e -> clearSlopeAndAspectLayer());

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new FlowLayout());
        super.mainPanel.add(centerPanel, BorderLayout.CENTER);

        JPanel parametersPanel = new JPanel();
        parametersPanel.setLayout(new GridBagLayout());
        centerPanel.add(parametersPanel);

        parametersPanel.add(new JLabel("显示风格:"), new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        slopeDisplayModeCmb = new JComboBox<>();
        parametersPanel.add(slopeDisplayModeCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        parametersPanel.add(new JLabel("透明度(%):"), new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        transparencyTxt = new JTextField();
        parametersPanel.add(transparencyTxt, new GridBagConstraints(1, 1, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        parametersPanel.add(new JLabel("最小可见高程:"), new GridBagConstraints(0, 2, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        minVisibleValueTxt = new JTextField();
        parametersPanel.add(minVisibleValueTxt, new GridBagConstraints(1, 2, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        parametersPanel.add(new JLabel("最大可见高程:"), new GridBagConstraints(0, 3, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        maxVisibleValueTxt = new JTextField();
        parametersPanel.add(maxVisibleValueTxt, new GridBagConstraints(1, 3, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        isArrowMoveCbx = new JCheckBox("流动");
        parametersPanel.add(isArrowMoveCbx, new GridBagConstraints(0, 4, 2, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        isShowSlopeAndAspectInfoChb = new JCheckBox("鼠标查看坡度坡向信息");
        parametersPanel.add(isShowSlopeAndAspectInfoChb, new GridBagConstraints(0, 5, 2, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        initializeDefaultValues();
    }

    private void initializeDefaultValues() {
        slopeDisplayModeCmb.removeAll();
        Enum[] enums = SlopeDisplayMode.getEnums(SlopeDisplayMode.class);
        for (Enum anEnum : enums) {
            slopeDisplayModeCmb.addItem((SlopeDisplayMode) anEnum);
        }
        slopeDisplayModeCmb.setSelectedItem(SlopeDisplayMode.FACE_AND_ARROW);

        transparencyTxt.setText("50");
        minVisibleValueTxt.setText("0");
        maxVisibleValueTxt.setText("90");

        isArrowMoveCbx.setSelected(false);
        isArrowMoveCbx.addActionListener(e -> {
            Geometry coverageRegion = slopeSetting.getCoverageRegion();
            clearSlopeAndAspectLayer();
            generateSlopeSetting(coverageRegion);
            TerrainLayers terrainLayers = sceneControl.getScene().getTerrainLayers();
            terrainLayers.setSlopeSetting(slopeSetting);
        });

        isShowSlopeAndAspectInfoChb.setSelected(false);
        isShowSlopeAndAspectInfoChb.addActionListener(e -> {
            if (isShowSlopeAndAspectInfoChb.isSelected()) {
                sceneControl.setAction(Action3D.CREATE_POINT);
            } else {
                sceneControl.setAction(Action3D.PAN);
            }
        });
    }

    @Override
    protected void doConfirm() {

    }

    @Override
    protected void doClose() {
        clearSlopeAndAspectLayer();
        for (Component component : getComponents()) {
            component.disable();
        }
    }

    private void generateSlopeSetting(Geometry coverageRegion) {
        slopeSetting = new SlopeSetting();
        slopeSetting.setDisplayStyle((SlopeDisplayMode) slopeDisplayModeCmb.getSelectedItem());
        slopeSetting.setOpacity(100 - Double.parseDouble(transparencyTxt.getText()));
        slopeSetting.setMinVisibleValue(Double.parseDouble(minVisibleValueTxt.getText()));
        slopeSetting.setMaxVisibleValue(Double.parseDouble(maxVisibleValueTxt.getText()));
        HashMap<Double, Color> colorTable = new HashMap<>();
        colorTable.put(0.0, Color.BLUE);
        colorTable.put(45.0, Color.GREEN);
        colorTable.put(90.0, Color.RED);
        slopeSetting.setColorDictTable(colorTable);
        slopeSetting.setArrowMove(isArrowMoveCbx.isSelected());
        slopeSetting.setCoverageRegion(coverageRegion);
    }

    private void clearSlopeAndAspectLayer() {
        if (slopeSetting != null) {
            slopeSetting.setDisplayStyle(SlopeDisplayMode.NONE);
        }
        TerrainLayers terrainLayers = sceneControl.getScene().getTerrainLayers();
        terrainLayers.setSlopeSetting(slopeSetting);
        slopeSetting = null;
        sceneControl.setAction(Action3D.PAN);
        sceneControl.removeTrackingListener(tracking3DListener);

        TrackingLayer3D trackingLayer = sceneControl.getScene().getTrackingLayer();
        int textTagIndex = trackingLayer.indexOf("Text");
        if (textTagIndex != -1) {
            trackingLayer.remove(textTagIndex);
        }
    }
}
